import java.lang.annotation.Retention;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.locks.ReentrantLock;

public class demo01 {


    public static void main(String[] args) {

        Ticket ticket = new Ticket();
//        new Thread(() -> {
//            for (int i = 0; i < 10; i++) {
//                ticket.saleTicket();
//            }
//        }, "AA").start();
//
//        new Thread(() -> {
//            for (int i = 0; i < 10; i++) {
//                ticket.saleTicket();
//            }
//        }, "BB").start();
//        new Thread(() -> {
//            for (int i = 0; i < 10; i++) {
//                ticket.saleTicket();
//            }
//        }, "CC").start();
//    }
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticket.saleTicketUseReentrantLock();
            }
        }, "AA").start();
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticket.saleTicketUseReentrantLock();
            }
        }, "BB").start();
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticket.saleTicketUseReentrantLock();
            }
        }, "CC").start();


    }
}

class Ticket {
    private int ticket = 300;

    //用synchronized 创建锁
    public synchronized void saleTicket() {
        int saleTicket = new Random().nextInt(10);
        if (ticket > 0 && saleTicket <= ticket) {   //得有票 且 要买的票不能超过库存票
            ticket = ticket - saleTicket;
            System.out.println(Thread.currentThread().getName() + " 卖出 : " + (saleTicket) + " 剩余： " + ticket);
        }
    }

    //创建可重入锁
    private final ReentrantLock lock = new ReentrantLock();

    public void saleTicketUseReentrantLock() {
        //上锁
        lock.lock();
        try {   //这里用try catch 是为了 不管有没有异常 都会最终把锁释放
            int saleTicket = new Random().nextInt(10);
            if (ticket > 0 && saleTicket <= ticket) {  //得有票 且 要买的票不能超过库存票
                ticket = ticket - saleTicket;
                System.out.println(Thread.currentThread().getName() + " 卖出 : " + (saleTicket) + " 剩余： " + ticket);
            }
        } finally {
            //释放锁
            lock.unlock();
        }

    }

}
